package com.hqq.thread.tls;

import java.util.Date;
import java.util.Calendar;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * ThreadLocal pattern
 * 示范了如何为每一个线程创建一个独立的空间.
 * 在这个例子里展示了SimpleDateFormat的线程安全用法
 * <p>
 * ThreadLocal类的功能类似于静态变量，使用了异常使他绑定在当前线程上.允许我们在线程安全的方式上使用静态变量
 * <p>
 * Created by heqianqian on 2017/7/2.
 */
public class App {

    public static void main(String[] args) {
        int counterDateValues = 0;
        int counterExceptions = 0;

        DateFormatCallable callableDf = new DateFormatCallable("dd/MM/yyyy", "15/12/2015");
        ExecutorService executor = Executors.newCachedThreadPool();

        Future<Result> futureResult1 = executor.submit(callableDf);
        Future<Result> futureResult2 = executor.submit(callableDf);
        Future<Result> futureResult3 = executor.submit(callableDf);
        Future<Result> futureResult4 = executor.submit(callableDf);

        try {
            Result[] results = new Result[4];
            results[0] = futureResult1.get();
            results[1] = futureResult2.get();
            results[2] = futureResult3.get();
            results[3] = futureResult4.get();

            for (int i = 0; i < results.length; i++) {
                counterDateValues = counterDateValues + printAndCountDates(results[i]);
                counterExceptions = counterExceptions + printAndCountExceptions(results[i]);
            }

            System.out.println("The List dateList contains " + counterDateValues + " date values");
            System.out.println("The List exceptionList contains " + counterExceptions + " exceptions");

        } catch (Exception e) {
            //System.out.println("Abnormal end of program. Program throws exception: " + e);
            e.printStackTrace();
        }
        executor.shutdown();
    }

    private static int printAndCountDates(Result result) {
        int counter = 0;
        for (Date dt : result.getDateList()) {
            counter++;
            Calendar cal = Calendar.getInstance();
            cal.setTime(dt);
            System.out.println(
                    cal.get(Calendar.DAY_OF_MONTH) + "." + cal.get(Calendar.MONTH) + "." + +cal.get(Calendar.YEAR));
        }
        return counter;
    }

    private static int printAndCountExceptions(Result res) {
        int counter = 0;
        for (String ex : res.getExceptionList()) {
            counter++;
            System.out.println(ex);
        }
        return counter;
    }
}
